package com.ujiuye.controller;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ujiuye.domain.dto.PageDTO;
import com.ujiuye.domain.po.Category;
import com.ujiuye.domain.po.Movie;
import com.ujiuye.domain.dto.SaveMovieDTO;
import com.ujiuye.domain.vo.CategoryListVO;
import com.ujiuye.domain.vo.PageVO;
import com.ujiuye.service.ICategoryService;
import com.ujiuye.service.IMovieService;
import com.ujiuye.utils.FileLoad;

import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.util.codec.binary.Base64;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.*;

@RestController
@CrossOrigin
@RequestMapping("movie")
@Slf4j
public class MovieController {

    @Autowired
    private IMovieService movieService;

    @Autowired
    private ICategoryService categoryService;

    @Value("${upload.dir}")
    private String uploadDir;

    // 播放电影的接口: 需要返回当前电影的信息和推荐列表
    @GetMapping("/playMovie")
    public Map<String, Object> playMovie(int movieId) {
        // 得到当前电影
        Movie movie = movieService.findById(movieId);
        // 得到被推荐的电影列表
        List<Movie> recommendMovieList = recommendMovieList(movieId);
        // 定义一个map用来封装movie和recommendMovieList,把它们一起返回到页面
        Map<String, Object> map = new HashMap<>();
        map.put("movie", movie);
        map.put("recommendMovieList", recommendMovieList);
        return map;
    }

    // 电影推荐列表接口
    public List<Movie> recommendMovieList(int movieId) {
        return movieService.recommendMovieList(movieId);
    }

    // 查询电影列表
    @GetMapping("/list")
    public PageVO<Movie> list(PageDTO<String> pageDTO) {
        PageVO<Movie> pageVO = movieService.page(pageDTO);
        return pageVO;
    }

    // 添加电影
    @PostMapping(value = "/save")
    public String save(@RequestParam(value = "file", required = false) MultipartFile file,
                       @RequestParam(value = "movie") String movieJson) {

        ObjectMapper objectMapper = new ObjectMapper();
        SaveMovieDTO saveMovieDTO = null;
        try {
            saveMovieDTO = objectMapper.readValue(movieJson, SaveMovieDTO.class);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }

        Movie movie = new Movie();
        BeanUtils.copyProperties(saveMovieDTO, movie);
        //将选择的数据从集合转化为字符串
        ArrayList<Integer> categories = saveMovieDTO.getCategories();
        StringJoiner stringJoiner = new StringJoiner(",");
        categories.forEach(item -> {
            stringJoiner.add(String.valueOf(item));
        });
        movie.setCategories(stringJoiner.toString());

        // 2.把pic文件中数据写到 新的文件中
        try {
            if (file != null) {
                // 把图片转成base64编码的字符串
                String base64Str = Base64.encodeBase64String(file.getBytes());
                // 把base64编码的字符串保存到对象中, 会插入到表的pic字段中
                movie.setPic(base64Str);
                // 上传缩略图
                FileLoad.uploadFile(file, uploadDir);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        movieService.save(movie);

        return "提交成功!";
    }

    @GetMapping("/editMovie")
    public Map<String, Object> editMovie(int movieId) {
        // 1.得到 这个电影的基本信息
        Movie movie = movieService.findById(movieId);
        // 2.所有的电影类型
        List<CategoryListVO> cateList = categoryService.findALl();
        // 3.定义一个map用来封装返回的数据
        Map<String, Object> dataMap = new HashMap<String, Object>();
        dataMap.put("movie", movie);
        dataMap.put("allCateList", cateList);
        return dataMap;
    }

    @GetMapping("/findAllCate")
    public List<CategoryListVO> findAllCate() {
        return categoryService.findALl();
    }

    @PostMapping("/deleteMovie")
    /*
     原来是这样定义的,movieId是int类型
     由于前端传递参数时是一个json对象,所以服务端接收时也应该使用Movie对象接受.
     由于前段使用的是Post请求,参数都是封装在requestbody中的,所有服务应该从
     requestbody中取数据,所以在参数前加@RequestBody注解
     */
    // public String deleteMovie( int movieId){
    public String deleteMovie(@RequestBody Movie movie) {
        //删除这个电影相关的数据:有三部分相关的数据:在movieService的deleteMovie中删除这三部分数据
        movieService.deleteMovie(movie.getId());
        return "删除成功";
    }

    @PostMapping("/updateMovie")
    public String updateMovie(@RequestParam(value = "file", required = false) MultipartFile file,
                              @RequestParam(value = "movie") String movieJson) {
        ObjectMapper objectMapper = new ObjectMapper();
        SaveMovieDTO saveMovieDTO = null;
        try {
            saveMovieDTO = objectMapper.readValue(movieJson, SaveMovieDTO.class);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }

        Movie movie = new Movie();
        BeanUtils.copyProperties(saveMovieDTO, movie);
        //将选择的数据从集合转化为字符串
        ArrayList<Integer> categories = saveMovieDTO.getCategories();
        StringJoiner stringJoiner = new StringJoiner(",");
        categories.forEach(item -> {
            stringJoiner.add(String.valueOf(item));
        });
        movie.setCategories(stringJoiner.toString());

        if (file != null) {
            try {
                // 把图片转成base64编码的字符串
                String base64Str = Base64.encodeBase64String(file.getBytes());
                // 把base64编码的字符串保存到对象中, 会插入到表的pic字段中
                movie.setPic(base64Str);
                // 上传缩略图
                FileLoad.uploadFile(file, uploadDir);

            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        movieService.update(movie);
        return "提交成功!";
    }


}
